package com.gxa.scdx.cloud.user.realm;

import com.gxa.scdx.cloud.user.pojo.User;
import com.gxa.scdx.cloud.user.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;

/**
 * @author  颜可翔
 * @version 1.0
 */
public class UserRealm extends AuthorizingRealm {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Object principal = principals.getPrimaryPrincipal();

        User user = (User) principal;
        String auth = user.getRoleId().toString();

        //权限分配 1为超管
        if ("1".equals(auth)) {
            info.addRole("1");
        }

        info.addRole("2");

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 把AuthenticationToken实质为UsernamePasswordToken，直接转换即可
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        //redis
        String cache = (String)redisTemplate.opsForValue().get(usernamePasswordToken.getUsername());     // 通过service查询用户名是否存在
        String password = cache.split(",")[0];
        String roleId = cache.split(",")[1];

        User user  =new User(usernamePasswordToken.getUsername(),password);
        user.setRoleId(Integer.parseInt(roleId));

        if (password == null)
            throw new UnknownAccountException("用户不存在！");

        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");                      // 加密方式，与注册一致
        hashedCredentialsMatcher.setHashIterations(11);                            // 加密次数，与注册一致
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);           // true是默认值，代表16机制值，如果设置false则为base64
        setCredentialsMatcher(hashedCredentialsMatcher);                           // 保存加密设置
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());    // 以用户名为加密盐值
        String realmName = getName();                                              // 当前realm对象的name，调用父类的getName()方法即可
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), credentialsSalt, realmName);

        return info;
    }
}